package ssm.integration.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.validation.annotation.Validated;

import javax.sql.DataSource;

/**
 * description: 持久层配置类-03
 * TODO：连接池，sqlSessionFactory, Mapper代理对象
 *      方式1：MyBatis外部配置文件 mybatis-config.xml，不推荐
 *
 * MyBatis 配置
 * 1. @Configuration 声明配置类
 * 2. @PropertySource(“classpath:jdbc.properties”) 读取外部配置文件
 * 3. @Value("${}") 读取配置文件字段信息
 * 4. @Bean 将数据库连接池DataSource放入IOC容器
 * 5. @Bean 将MyBatis自带的SqlSessionFactoryBean注入IOC容器，用于创建SqlSessionFactory
 * 6. @Bean 将设置SqlSessionFactory配置信息
 * 7. @Bean 将Mapper代理对象MapperScannerConfigurer注入IOC容器，通过扫描指定路径下的Mapper接口，生成代理对象。
 *
 * 问题：
 * 1. 不能将 DataSource 和 MyBatis组件 SqlSessionFactoryBean、MapperScannerConfigurer 配置文件写到一起
 * 2. MyBatis组件加载优先于 @Value("${}") 读取配置文件字段信息，导致@Value注解不生效
 * 3. 解决：分开配置，写到不同的类，将 DataSource 的配置单独写到 DataSourceJavaConfig 配置类
 */

@Configuration
public class MapperJavaConfig {

    // DataSource 不能和 MyBatis组件 SqlSessionFactoryBean、MapperScannerConfigurer 配置写到一个配置文件

//    @Value("${jdbc.user}")
//    private String user;
//
//    @Value("${jdbc.password}")
//    private String password;
//
//    @Value("${jdbc.url}")
//    private String url;
//
//    @Value("${jdbc.driver}")
//    private String driver;
//
//    // 数据库连接池配置
//    @Bean
//    public DataSource dataSource(){
//        DruidDataSource dataSource = new DruidDataSource();
//        dataSource.setUsername(user);
//        dataSource.setPassword(password);
//        dataSource.setUrl(url);
//        dataSource.setDriverClassName(driver);
//        return dataSource;
//    }

    // MyBatis自带的SqlSessionFactoryBean注入IOC容器，方式1：MyBatis外部配置文件 mybatis-config.xml
    @Bean
    public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) throws Exception {

        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        //指定配置文件等信息

        //指定数据库连接池对象
        sqlSessionFactoryBean.setDataSource(dataSource);

        //指定外部的mybatis配置文件，导入spring.core 包下的Resource
        Resource resource = new ClassPathResource("mybatis-config.xml");
        sqlSessionFactoryBean.setConfigLocation(resource);

        // 用于创建SqlSessionFactory
        SqlSessionFactory object = sqlSessionFactoryBean.getObject();

        return sqlSessionFactoryBean;
    }

    //配置Mapper实例扫描工厂，mapper代理对象加入到ioc
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        // 通过扫描指定路径下的Mapper接口，生成代理对象。
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        //mapper接口和mapper.xml所在的共同包
        mapperScannerConfigurer.setBasePackage("ssm.integration.mapper");
        return mapperScannerConfigurer;
    }
}
